package cn.oversky.eom;

import cn.oversky.eom.rule.IFormValueRule;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import static cn.oversky.eom.utils.PropertiesUtils.isNotNull;


/**
 * 虽然目前可以使用 map类型，但是抽出映射对象，以便拓展
 * Excel-Object Mapping 类
 * TODO
 * <ul>后期拓展：
 *      <li>类属性
 *      <li>字段字典转换
 *      <li>自定义类型
 * @email CorvusY@foxmail.com
 * @date 2016/11/7 11:51.
 * Now is history !
 */
public class EOMapping {

    String fieldName;
    String columnName;
    Object fieldValue;
    Object defaultValue;
    EOMFieldConvert convert;
    Map map;
    Object ignoreValue;

    String formula;

    EOValueFormat valueFormat;

    String dateFormat;

    /**
     * 是否需要模板表头校验
     */
    boolean thRequired = true;

    public EOMapping setValueFormat(EOValueFormat valueFormat) {
        this.valueFormat = valueFormat;
        return this;
    }

    /**
     * 值校验器 2017-4-18 14:48:15 ye
     */
    IFormValueRule rule;

    /**
     * 原始值校验器 2018-2-11 14:36:31 ye
     */
    IFormValueRule valueRule;

    /**
     * 列值的强制类型。
     */
    public Class forceType;

    public static Map getRuleMap( Map<String, EOMapping> excelMap ) {
        Map<String, IFormValueRule> ruleMap = new LinkedHashMap<String, IFormValueRule>();
        Collection<EOMapping> values = excelMap.values();
        for (EOMapping eoMapping : values) {
            if( isNotNull( eoMapping.valueRule ) ) {
                ruleMap.put(eoMapping.fieldName, eoMapping.valueRule);
            }
        }
        return ruleMap;
    }

    public EOMapping(String fieldName,
                     String columnName,
                     Object fieldValue,
                     EOMFieldConvert convert ,
                     IFormValueRule rule) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.fieldValue = fieldValue;
        this.convert = convert;
        this.rule = rule;
    }

    public EOMapping(String fieldName,
                     String columnName,
                     Object fieldValue,
                     EOMFieldConvert convert ,
                     Map map,
                     IFormValueRule rule) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.fieldValue = fieldValue;
        this.convert = convert;
        this.map = map;
        this.rule = rule;
    }

    public EOMapping(String fieldName,
                     String columnName,
                     Object fieldValue,
                     EOMFieldConvert convert ,
                     Map map,
                     IFormValueRule rule,
                     Object ignoreValue) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.fieldValue = fieldValue;
        this.convert = convert;
        this.map = map;
        this.rule = rule;
        this.ignoreValue = ignoreValue;
    }

    public EOMapping(String fieldName, String columnName, Object fieldValue, EOMFieldConvert convert ) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.fieldValue = fieldValue;
        this.convert = convert;
    }

    public EOMapping(String fieldName, String columnName, Object fieldValue ) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.fieldValue = fieldValue;
    }

    public EOMapping(String fieldName, String columnName) {
        this.fieldName = fieldName;
        this.columnName = columnName;
    }

    public EOMapping(String fieldName, String columnName, Map map ) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.map = map;
    }

    public EOMapping(String fieldName, String columnName, Map map, IFormValueRule rule) {
        this.fieldName = fieldName;
        this.columnName = columnName;
        this.map = map;
        this.rule = rule;
    }

    public EOMapping setForceType( Class forceType ) {
        this.forceType = forceType;
        return this;
    }

    public EOMapping setIgnoreValue(Object ignoreValue) {
        this.ignoreValue = ignoreValue;
        return this;
    }

    public IFormValueRule getValueRule() {
        return valueRule;
    }

    public EOMapping setValueRule(IFormValueRule valueRule) {
        this.valueRule = valueRule;
        return this;
    }

    public IFormValueRule getRule() {
        return rule;
    }

    public EOMapping setRule(IFormValueRule rule) {
        this.rule = rule;
        return this;
    }

    public String getColumnName() {
        return this.columnName;
    }

    public EOMapping setDefaultValue( Object defaultValue ) {
        this.defaultValue = defaultValue;
        return this;
    }

    public String getDateFormat() {
        return dateFormat;
    }

    public EOMapping setDateFormat(String dateFormat) {
        this.dateFormat = dateFormat;
        return this;
    }

    public boolean isThRequired() {
        return thRequired;
    }

    public EOMapping setThRequired(boolean thRequired) {
        this.thRequired = thRequired;
        return this;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public EOMFieldConvert getConvert() {
        return convert;
    }

    public void setConvert(EOMFieldConvert convert) {
        this.convert = convert;
    }

    public Object getDefaultValue() {
        return defaultValue;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public Object getFieldValue() {
        return fieldValue;
    }

    public void setFieldValue(Object fieldValue) {
        this.fieldValue = fieldValue;
    }

    public String getFormula() {
        return formula;
    }

    public void setFormula(String formula) {
        this.formula = formula;
    }

    public Object getIgnoreValue() {
        return ignoreValue;
    }

    public Map getMap() {
        return map;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public EOValueFormat getValueFormat() {
        return valueFormat;
    }
}
